package organizer;

import java.util.List;

/**
 * Visits files recursively depth-first through directories
 * @author dawong
 */
public class DepthFirstAlgorithm<N> {

    private INodeReader<N> nodeReader;

    public DepthFirstAlgorithm(INodeReader<N> nodeReader) {
        this.nodeReader = nodeReader;
    }

    public void visit(N rootNode, INodeVisitor<N> visitor) {
        visit(rootNode, visitor, null);
    }

    public void visit(N rootNode, INodeVisitor<N> visitor, IProgressMonitor progress) {
        visitor.pre(rootNode);
        visitHelper(rootNode, visitor, progress);
        visitor.post(rootNode);
    }
    
    private void visitHelper(N node, INodeVisitor<N> visitor, IProgressMonitor progress) {
        if (progress != null && progress.isCanceled())
            return;
        visitor.visit(node);
        List<N> childNodes = nodeReader.getChildren(node);
        if (childNodes != null && childNodes.size() > 0) {
            for (N childNode : childNodes) {
                if (progress != null && progress.isCanceled())
                    return;
                if (nodeReader.hasChildren(childNode)) {
                    // recursive call
                    visitor.pre(childNode);
                    visitHelper(childNode, visitor, progress);
                    visitor.post(childNode);
                } else {
                    visitor.pre(childNode);
                    visitor.visit(childNode);
                    visitor.post(childNode);
                }
            }
        }
    }

}
